home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp95 / freyja.exe / lha / MAKEEXM.C < prev    next >
C/C++ Source or Header  |  1992-04-13  |  4KB  |  171 lines

  1. /* MAKEEXM.C -- Make a .EXE File Into a .EXM File
  2.  
  3.     Written March 1992 by Craig A. Finseth
  4.     Copyright 1992 by Craig A. Finseth
  5.  
  6. This program takes one or two arguments:
  7.  
  8. The first argument is always the name of the .EXM file.  If no suffix
  9. is supplied, the suffix ".EXM" is used.  This file is updated in place.
  10.  
  11. The second argument is optional.  If present, it gives the name of a
  12. .MAP file.  The extension is always forced to ".MAP".  If not present,
  13. the first argument is used to name the .MAP file.
  14. */
  15.  
  16. #include <stdio.h>
  17. #include "fgenlib.h"
  18.  
  19. char t_attrib;            /* for libasm.asm */
  20.  
  21. unsigned Find(char *map_file);
  22. FLAG PSetExt(char *name, char *ext, FLAG force);
  23. void Update(char *exm_file, unsigned address);
  24.  
  25. /* ------------------------------------------------------------ */
  26.  
  27. int
  28. main(argc, argv)
  29.     int argc;
  30.     char *argv[];
  31.     {
  32.     char *map_file;
  33.     char *exm_file;
  34.     unsigned address;
  35.  
  36.     if (argc < 2 || argc > 3) {
  37. usage:
  38.         xprintf("Make .EXM file program.\r\n\
  39. usage is:  makeexm <.exm file> <.map file>\r\n");
  40.         exit(1);
  41.         }
  42.  
  43.     exm_file = argv[1];
  44.     if (argc == 3)
  45.         map_file = argv[2];
  46.     else    map_file = argv[1];
  47.  
  48.         /* find value */
  49.  
  50.     address = Find(map_file);
  51.  
  52.         /* update .exm file */
  53.  
  54.     Update(exm_file, address);
  55.  
  56.     xprintf("Converted %s, data segment %x\r\n", exm_file, address);
  57.     exit(0);
  58.     }
  59.  
  60.  
  61. /* ------------------------------------------------------------ */
  62.  
  63. /* Find the start of the data segment.  This is the first of either
  64. _INIT_ or _DATA. Print a message and abort if error. */
  65.  
  66. unsigned
  67. Find(char *map_file)
  68.     {
  69.     char fname[FNAMEMAX];
  70.     char buf[BUFFSIZE];
  71.     unsigned val;
  72.     FILE *fp;
  73.  
  74.     xstrcpy(fname, map_file);
  75.     PSetExt(fname, "MAP", TRUE);
  76.  
  77.     if ((fp = fopen(fname, "r")) == NULL) {
  78.         xeprintf("Unable to open map file '%s'.\r\n", fname);
  79.         exit(1);
  80.         }
  81.  
  82.     while (fgets(buf, sizeof(buf), fp) != NULL) {
  83.         if (strlen(buf) < 27) continue;
  84.         if (!strnequ(&buf[22], "_DATA", 5) && 
  85.              !strnequ(&buf[22], "_INIT_", 6))
  86.             continue;
  87.  
  88.         buf[5] = NUL;
  89.         if (!SToN(&buf[1], &val, 16)) continue;
  90.         fclose(fp);
  91.         return(val);
  92.         }
  93.  
  94.     fclose(fp);
  95.     xeprintf("Unable to find start of data segment in %s.\r\n", fname);
  96.     exit(1);
  97.     }
  98.  
  99.  
  100. /* ------------------------------------------------------------ */
  101.  
  102. /* Set the extension part of a name to EXT.  If FORCE is TRUE, set the
  103. extension even if there is one.  Return TRUE if the extension was set
  104. or FALSE if it wasn't.  EXT doesn't include the period!! */
  105.  
  106. FLAG
  107. PSetExt(char *name, char *ext, FLAG force)
  108.     {
  109.     char *cptr;
  110.     char *c1;
  111.  
  112.     cptr = c1 = name + strlen(name);
  113.     while (cptr > name && *cptr != '.' && *cptr != '/') cptr--;
  114.     if (*cptr != '.') cptr = c1;
  115.     if (force || !*cptr) {
  116.         *cptr++ = '.';
  117.         xstrcpy(cptr, ext);
  118.         return(TRUE);
  119.         }
  120.     return(FALSE);
  121.     }
  122.  
  123.  
  124. /* ------------------------------------------------------------ */
  125.  
  126. /* Find the start of the data segment.  This is the first of either
  127. _INIT_ or _DATA. Print a message and abort if error. */
  128.  
  129. void
  130. Update(char *exm_file, unsigned address)
  131.     {
  132.     char fname[FNAMEMAX];
  133.     char buf[BUFFSIZE];
  134.     int amt;
  135.     int fd;
  136.  
  137.     xstrcpy(fname, exm_file);
  138.     PSetExt(fname, "EXM", FALSE);
  139.  
  140.     if ((fd = open(fname, 2, 0666)) < 0) {
  141.         xeprintf("Unable to open exm file '%s'.\r\n", fname);
  142.         exit(1);
  143.         }
  144.  
  145.     if ((amt = read(fd, buf, sizeof(buf))) <= 0x1b) {
  146.         xeprintf("Unable to read exm file %s.\r\n", fname);
  147.         close(fd);
  148.         exit(1);
  149.         }
  150.  
  151. /* set the new magic number */
  152.     buf[0] = 0x44;
  153.     buf[1] = 0x4c;
  154.  
  155. /* set the data segment start */
  156.     buf[0x1a] = address;
  157.     buf[0x1b] = address >> 8;
  158.  
  159.     lseek(fd, 0L, 0);
  160.     if (write(fd, buf, amt) != amt) {
  161.         xeprintf("Unable to update exm file %s.\r\n", fname);
  162.         close(fd);
  163.         exit(1);
  164.         }
  165.  
  166.     close(fd);
  167.     }
  168.  
  169.  
  170. /* end of MAKEEXM.C -- Make a .EXE File Into a .EXM File */
  171.